package wre.data;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.constraint.StrMinMax;
import org.supercsv.cellprocessor.constraint.Unique;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.exception.SuperCSVReflectionException;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;

import wre.Retort;
import wre.Word;
import wre.logic.InputParser;

public class WordDAO {
	private Map<String, Word> words;
	private final static CellProcessor[] processors = new CellProcessor[] {
			new ParseInt(), new StrMinMax(1, 30), new ParseInt() };
	private static final String FILENAME = "word.csv";
	private static final String[] HEADER = new String[] { "id", "word", "count" };

	private WordDAO() {

	}

	public static WordDAO getInstance() {
		Map<String, Word> words = new HashMap<String, Word>();
		WordDAO ret = new WordDAO();
		try {
			ICsvBeanReader inFile = new CsvBeanReader(new FileReader(FILENAME),
					CsvPreference.EXCEL_PREFERENCE);
			try {
				final String[] header = inFile.getCSVHeader(true);
				Word word;
				while ((word = inFile.read(Word.class, header, processors)) != null) {
					words.put(word.getWord(), word);
				}
			} finally {
				inFile.close();
			}
			ret.setWords(words);
		} catch (SuperCSVReflectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return ret;

	}

	public void addWord(int id, String word, boolean updateCount) {
		String myWord = word.trim().toLowerCase();
		if (myWord.length() > 2) {
			if (words.containsKey(myWord) && updateCount) {
				words.get(myWord).setCount(words.get(myWord).getCount() + 1);
			} else {
				words.put(myWord, new Word(id, myWord, 0));
			}
		}
	}

	public void addPhrase(int id, String phrase, boolean updateCount) {
		InputParser inputParser = InputParser.getInstance();
		List<String> synonyms = inputParser.parseInput(phrase);
		for (String word : synonyms) {
			addWord(id, word, updateCount);
		}
	}

	public Map<String, Word> getWords() {
		return words;
	}

	public void setWords(Map<String, Word> words) {
		this.words = words;
	}

	public static void main(String[] args) {
		WordDAO dao = getInstance();
		dao.addPhrase(470518469, "Hey, watch your mouth", false);
		dao.addPhrase(111510280, "Make sure it's long enough", false);
		dao.addPhrase(-1310051655, "YOU don't make any sense", false);
		dao.addPhrase(-1991051528, "you are an idiot", false);
		dao.addPhrase(395349139,
				"I heard some people talking about that the other day", false);
		dao.addPhrase(111510280,
				"Push harder", false);
		dao.writeData();
	}

	public void writeData() {
		ICsvBeanWriter writer;
		try {
			writer = new CsvBeanWriter(new FileWriter(new File(FILENAME)),
					CsvPreference.EXCEL_PREFERENCE);

			try {

				// set up some data to write
				Iterator<Entry<String, Word>> iterator = words.entrySet()
						.iterator();
				Entry<String, Word> entry = null;
				writer.writeHeader(HEADER);
				while (iterator.hasNext()) {
					entry = iterator.next();
					writer.write(entry.getValue(), HEADER);
				}

				// the actual writing

			} finally {
				writer.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
